﻿@page "/index"
@inject IJSRuntime JsRuntime
@inject IPoiQuery PoiQuery
@inject ITravelSubject TravelSubject
@inject IAuxiliaryFunction AuxiliaryFunction
@inject IPopupService PopupService
@inject IAuxiliaryFunction AuxiliaryFunction
@inject ILocalStorageService LocalStorage
@implements IDisposable

@*地图*@
<div id="boxmap" style="position:absolute;left:0px;top:0px;height:100%;width:100%;" class="preventselecttext">
    <div id="allmap" style="height:100%"></div>
    <ul class="btn-wrap" style="z-index: 99;display: none;" id="umarker">
        <MButton Outlined Color="#4DB6AC" OnClick="ClearLayer">清除标记</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="StopAddMarker">停止标记</MButton>
    </ul>
    <ul class="btn-wrap" style="display: none;" id="umeasureline">
        <MButton Outlined Color="#4DB6AC" OnClick="StartDistanceMeasure">继续测距</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="StopDistanceMeasure">停止测距</MButton>
    </ul>
    <ul class="btn-wrap" style="z-index: 99;display: none" id="umeasurearea">
        <MButton Outlined Color="#4DB6AC" OnClick="@(()=>DrawShape("rectangle"))">矩形</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="@(()=>DrawShape("polygon"))">多边形</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="@(()=>DrawShape("circle"))">圆</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="ClearLayer">清除标记</MButton>
        <MButton Outlined Color="#4DB6AC" OnClick="StopAreaMeasure">停止标记</MButton>
    </ul>
</div>

@*搜索栏*@
<MToolbar Dense Floating Elevation="50" Style="z-index:99;border-radius:5px">
    <MTextField HideDetails="true"
                SingleLine
                Color="#4DB6AC"
                Label="搜索地点，路线..."
                Style="width:280px"
                @bind-Value="@PoiKeyword" />
    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="PoiSearch" @attributes="@context.Attrs">
                <MIcon>mdi-magnify</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>地点搜索</span>
        </ChildContent>
    </MTooltip>

    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon @attributes="@context.Attrs" OnClick="@(()=>IsRoutePlanningHidden=!IsRoutePlanningHidden)"
                     Color="@(!IsRoutePlanningHidden?"#EB8110":"#888888")">
                <MIcon>mdi-vector-polyline</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>路径规划</span>
        </ChildContent>
    </MTooltip>

    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="ToMapCenter" @attributes="@context.Attrs">
                <MIcon>mdi-crosshairs-gps</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>返回市中心</span>
        </ChildContent>
    </MTooltip>

    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="()=> IsSearchSettingsShow = true" @attributes="@context.Attrs">
                <MIcon>mdi-dots-vertical</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>搜索设置</span>
        </ChildContent>
    </MTooltip>
</MToolbar>

@*搜索结果*@
<MCard Elevation="80"
       Class="@(IsSearchResultHidden? "hidden" : string.Empty)"
       Style="z-index:99;background-color:#f5f5f5;border-radius:5px;position:absolute;top:70px;left:12px;width:443px;height:720px">
    <div style="position:absolute;width:100%;height:648px;background-color:#f5f5f5;">
        <MFooter Padless Style="background-color:#4DB6AC;height:42px;border-radius:5px 5px 0 0">
            <MRow Justify="JustifyTypes.Center" NoGutters Class="text-center">
                <MLabel Style="color:#f5f5f5;font-size:large">搜索结果</MLabel>
                <MButton Color="#4DB6AC" Icon
                         OnClick="()=>IsSearchResultHidden=true"
                         style="right:1px;position:absolute;top:5px;width:20px;height:20px">
                    <MIcon Color="white" Size="4">mdi-close</MIcon>
                </MButton>
            </MRow>
        </MFooter>
        @if (IsNoQueryResult)
        {
            <MContainer Style="width:100%;height:100%">
                <MLabel Style="font-size:x-large;font-weight:400;position:absolute;top:48px;left:24px">暂无搜索结果</MLabel>
                <MIcon Size="64" Color="#aaaaaa" Style="position:absolute;top:280px;left:180px">mdi-content-paste</MIcon>
            </MContainer>
        }
        else
        {
            <MVirtualScroll Height=300 OverscanCount=5 ItemSize="72" Items="PoiResults" Style="height:100%;width:100%" Class="ds">
                <ItemContent>
                    <MListItem>
                        @*定位按钮*@
                        <MListItemAction>
                            <MButton Fab Depressed OnClick="@((e)=>GoToPoi(e,context))">
                                <MIcon Color="#4DB6AC">mdi-map-marker</MIcon>
                            </MButton>
                        </MListItemAction>
                        @*详细信息*@
                        <MListItemContent>
                            <MListItemTitle>
                                <strong>@context.name</strong>
                            </MListItemTitle>
                            <MLabel Style="font-size:small">地址：@context.address</MLabel>
                            <MLabel Style="font-size:small">电话：@(context.telephone is null ? "暂无" : context.telephone)</MLabel>
                        </MListItemContent>
                    </MListItem>
                </ItemContent>
            </MVirtualScroll>
        }
        <MFooter Padless Style="background-color:#f5f5f5;height:30px;border-radius:0 0 5px 5px">
            <MRow Justify="JustifyTypes.Center" NoGutters>
                <MSpacer />
                <MSpacer />
                <MSpacer />
                <MButton Icon XSmall OnClick="PreviousPage">
                    <MIcon Color="#444444">mdi-arrow-left</MIcon>
                </MButton>
                <MSpacer />
                <MLabel Style="font-size:x-small;top:3px;color:#444444">第 @(CurrentPage + 1) 页</MLabel>
                <MSpacer />
                <MButton Icon XSmall OnClick="NextPage">
                    <MIcon Color="#444444">mdi-arrow-right</MIcon>
                </MButton>
                <MSpacer />
                <MSpacer />
                <MSpacer />
            </MRow>
        </MFooter>
    </div>
</MCard>

@*路线规划*@
<MCard Elevation="50"
       Class="@(IsRoutePlanningHidden? "hidden" : string.Empty)"
       Style="z-index:99;border-radius:5px;top:70px;position:absolute;right:12px;width:400px;Height:720px;background-color:#f5f5f5">
    <div style="position:absolute;width:100%;height:660px;background-color:#f5f5f5">
        <MTabs @bind-Value="TravelMode" BackgroundColor="#4DB6AC" Dark FixedTabs Style="border-radius:5px 5px 0 0">
            <MTab>
                <MIcon>mdi-walk</MIcon>
                <MLabel Style="margin-left:10px">步行</MLabel>
            </MTab>
            <MTab>
                <MIcon>mdi-bicycle</MIcon>
                <MLabel Style="margin-left:10px">骑行</MLabel>
            </MTab>
            <MTab>
                <MIcon>mdi-car</MIcon>
                <MLabel Style="margin-left:10px">驾车</MLabel>
            </MTab>
        </MTabs>
        <MTextField @bind-Value="@(StartPoint.Address)"
                    HideDetails="true"
                    Solo Readonly=true
                    Label="选择起点"
                    Color="#F54336"
                    Style="width:80%;margin-top:14px;margin-left:10%"
                    PrependInnerIcon="mdi-map-marker-radius"
                    AppendIcon="mdi-map-marker-plus-outline"
                    OnAppendClick="SelectStartPoint" />
        <MCard Height="200" Elevation="30" Style="border-radius:5px;width:80%;margin-left:10%;margin-top:14px">
            <MIcon Style="top:10px;left:13px">mdi-map-marker-radius</MIcon>
            <MLabel Style="top:13px;left:13px">选择经过点</MLabel>
            <MLabel Style="color:white" Class="preventselecttext">11111111111111111</MLabel>
            <MIcon Style="top:10px;left:6px" OnClick="SelectTravelPoint">mdi-map-marker-plus-outline</MIcon>
            <MVirtualScroll OverscanCount=5 ItemSize="48" Items="TravelPoints" Style="width:100%;height:154px;margin-top:20px">
                <ItemContent>
                    <MListItem>
                        <MIcon Small Color="#666666">mdi-checkbox-blank-circle-outline</MIcon>
                        <MLabel Style="color:#666666;margin-left:2px">···</MLabel>
                        @*详细信息*@
                        <MListItemContent>
                            <MLabel Style="font-size:small;font-weight:400;margin-left:2px;color:#333333">@context.Address</MLabel>
                        </MListItemContent>
                        @*删除按钮*@
                        <MButton Depressed
                                 XSmall
                                 Style="left:10px;background-color:#dddddd;"
                                 OnClick="@(async ()=>{await RemoveTravelPoint(context);})">
                            <MIcon Color="#4DB6AC" Small>mdi-trash-can-outline</MIcon>
                        </MButton>
                    </MListItem>
                    <MDivider />
                </ItemContent>
            </MVirtualScroll>
        </MCard>
        <MTextField @bind-Value="@(EndPoint.Address)"
                    HideDetails="true"
                    Solo Readonly=true
                    Label="选择终点"
                    Color="#6CBB00"
                    Style="width:80%;margin-top:14px;margin-left:10%"
                    PrependInnerIcon="mdi-map-marker-radius"
                    AppendIcon="mdi-map-marker-plus-outline"
                    OnAppendClick="SelectEndPoint" />
        <MTabs @bind-Value="Tactics" SliderColor="#4DB6AC" Color="#4DB6AC" CenterActive Style="border-radius:5px;width:80%;margin-left:10%;margin-top:14px">
            <MTab>
                <MIcon>mdi-thumb-up</MIcon>
                <MLabel Style="margin-left:10px">推荐路线</MLabel>
            </MTab>
            <MTab>
                <MIcon>mdi-highway</MIcon>
                <MLabel Style="margin-left:10px">不走高速</MLabel>
            </MTab>
            <MTab>
                <MIcon>mdi-clock-time-five</MIcon>
                <MLabel Style="margin-left:10px">躲避拥堵</MLabel>
            </MTab>
            <MTab>
                <MIcon>mdi-chart-timeline-variant-shimmer</MIcon>
                <MLabel Style="margin-left:10px">距离较短</MLabel>
            </MTab>
        </MTabs>
        <MCard Height="240" Elevation="30" Style="border-radius:5px;width:80%;margin-left:10%;margin-top:14px;">
            <MIcon Style="top:10px;left:13px">mdi-map-marker-path</MIcon>
            <MLabel Style="top:13px;left:13px">规划结果</MLabel>
            <MLabel Style="color:white" Class="preventselecttext">111111111111111111</MLabel>
            <MIcon Style="top:10px;left:14px" OnClick="SearchRoute">mdi-magnify</MIcon>
            <div style="width:100%;height:194px;margin-top:20px;overflow-y:scroll;overflow-x:hidden;border-radius:0 0 5px 5px" class="ds">
                @if(RouteSteps is not null)
                {
                    <MTimeline AlignTop Dense>
                    @foreach (var item in RouteSteps)
                    {
                        <MTimelineItem Color="@DotColor" Small>
                            <MAlert Value Color="@AlertColor" Style="margin-right:12px">
                            <MLabel Style="font-size:small;font-weight:400;">
                                @(item.instruction.CleanUp())
                            </MLabel>
                        </MAlert>
                        </MTimelineItem>
                    }
                    </MTimeline>
                }
            </div>
        </MCard>
    </div>
</MCard>

@*搜索设置窗口*@
<MDialog @bind-Value="IsSearchSettingsShow" Width="480" Style="height:230px">
    <MCard>
        <MFooter Color="#4DB6AC" Style="height:42px;" Padless>
            <MCol Class="text-center" Cols="12">
                <p style="color:white">搜索服务设置</p>
            </MCol>
        </MFooter>
        <MDivider />
        <MContainer>
            @*搜索范围设置*@
            <MContainer>
                <MLabel>搜索范围设置</MLabel>
                <MRadioGroup @bind-Value="SearchMode">
                    <MRadio Label="全城搜索" Color="#4DB6AC" Value="@(SearchMode.WholeCity)" />
                    <MRadio Label="附近搜索" Color="#4DB6AC" Value="@(SearchMode.Scoped)" />
                    <MRadio Label="景点搜索" Color="#4DB6AC" Value="@(SearchMode.ScenicSpot)" />
                </MRadioGroup>
                <MLabel Style="position:sticky; top:20px">范围搜索半径(m):</MLabel>
                <MTextField @bind-Value="Scope" Solo Dense Style="position:sticky; margin-top:10px" />
            </MContainer>
            <MCardActions>
                <MButton Text Color="#4DB6AC"
                         Style="right:20px;position:absolute;bottom:20px"
                         OnClick="@(()=>IsSearchSettingsShow=false)">确定</MButton>
            </MCardActions>
        </MContainer>
    </MCard>
</MDialog>

@*用户设置窗口*@
<MDialog @bind-Value="IsUserSettingsShow" Width="400">
    <MContainer>
        <MRow Justify=JustifyTypes.SpaceAround>
            <MCard Width="400">
                <MImage Height="200" Src="imgs/userback.png">

                    <MAppBar Flat Color="rgba(0, 0, 0, 0)">
                        <MSpacer></MSpacer>
                        <MButton Color="white" Icon OnClick="@(()=>IsUserSettingsShow=false)">
                            <MIcon>mdi-arrow-right</MIcon>
                        </MButton>
                    </MAppBar>

                    <MCardTitle Class="white--text mt-8">
                        <MAvatar Size=56 Color="#C8BFE7">
                            <span style="font-size:x-large;color:#8153A6">@(CurrentUser.Username[0])</span>
                        </MAvatar>
                        <p class="ml-3">@CurrentUser.Username</p>
                    </MCardTitle>

                </MImage>
                <MCardText>
                    <MDivider>基本信息</MDivider>
                    <MSpacer />
                    <div class="font-weight-bold ml-8 mb-2">用户账号：@(CurrentUser.Account)</div>
                    <div class="font-weight-bold ml-8 mb-2">登录时间：@(LoginTime)</div>
                    <div style="text-align:center" class="mt-8">
                        <MButton Outlined Color="#4DB6AC" Class="mr-5">修改用户名</MButton>
                        <MButton Outlined Color="#4DB6AC">修改密码</MButton>
                    </div>
                    <MDivider Class="mt-8">我的标绘</MDivider>
                    <MCard Elevation="2" Style="height:240px;width:320px;margin-left:28px;margin-top:28px">
                        <MVirtualScroll Items="DraftsList" OverscanCount=5 ItemSize="100" Class="preventselecttext ds">
                            <ItemContent>
                                <MListItem>

                                    <MListItemContent>
                                        <MIcon Size="32" Style="left:10px;position:absolute">mdi-map-legend</MIcon>
                                        <MLabel Style="font-size:medium;color:#444444;left:36px">@context.Name</MLabel>
                                        <MLabel Style="font-size:xx-small;color:white;left:36px">1</MLabel>
                                        <MLabel Style="font-size:smaller;left:36px">创建时间：@context.CreateTime.ToString()</MLabel>
                                    </MListItemContent>

                                    <MListItemAction>
                                        <MIcon Small OnClick="@(()=>DeleteDraft(context.ID))">
                                            mdi-trash-can-outline
                                        </MIcon>
                                        <MLabel Style="font-size:xx-small;color:white;">1</MLabel>
                                        <MIcon Small OnClick="@(()=>LoadDraft(context))">
                                            mdi-open-in-new
                                        </MIcon>
                                    </MListItemAction>

                                </MListItem>
                                <MDivider />
                            </ItemContent>
                        </MVirtualScroll>
                    </MCard>

                </MCardText>
            </MCard>
        </MRow>
    </MContainer>
</MDialog>

@*用户栏/工具箱*@
<MToolbar Dense Floating Elevation="50" Style="z-index:98;border-radius:5px;right:10px;position:absolute" Class="preventselecttext">
    <MMenu OffsetY>
        <ActivatorContent>
            <MButton Icon Color=@(CurrentWeather.Sunny?"yellow":"blue") @attributes="@context.Attrs">
                <MIcon>@(CurrentWeather.Sunny?"mdi-weather-sunny":"mdi-weather-pouring")</MIcon>
            </MButton>
            <MLabel>@(CurrentWeather.Sunny?"晴":"雨")</MLabel>
            <MLabel Style="color:white">11</MLabel>
        </ActivatorContent>
        <ChildContent>
            <MCard Width="180" Height="160" Style="padding:10px">
                <div class="font-weight-bold ml-6 mb-2" style="color:#666666;font-size:small">当前温度：@CurrentWeather.Temperature °C</div>
                <div class="font-weight-bold ml-6 mb-2" style="color:#666666;font-size:small">风力等级：@CurrentWeather.Wind m/s</div>
                <div class="font-weight-bold ml-6 mb-2" style="color:#666666;font-size:small">相对湿度：@CurrentWeather.RHU%</div>
                <div class="font-weight-bold ml-6 mb-2" style="color:#666666;font-size:small">3h降雨量：@CurrentWeather.RainIn3h mm</div>
                <div class="font-weight-bold ml-6 mb-2" style="color:#666666;font-size:small">6h降雨量：@CurrentWeather.RainIn6h mm</div>
            </MCard>
        </ChildContent>
    </MMenu>
    <MDivider Vertical Inset />
    <MMenu OffsetY>
        <ActivatorContent>
            <MButton Icon Color="@(IsUsingTool?"#0088E3":"#888888")" @attributes="@context.Attrs">
                <MIcon>mdi-tools</MIcon>  
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <MList>
                <MDivider />
                <MListItem OnClick="StartAddMarker">
                    <MListItemContent>
                        <MListItemTitle>
                            <MIcon Size="16" Color="@(IsUsingMarkerTool?"#0088E3":"#888888")">mdi-map-marker</MIcon>
                            <MLabel>位置标记</MLabel>
                        </MListItemTitle>
                    </MListItemContent>
                </MListItem>
                <MDivider />
                <MListItem OnClick="StartDistanceMeasure">
                    <MListItemContent>
                        <MListItemTitle>
                            <MIcon Size="16" Color="@(IsUsingDistanceTool?"#0088E3":"#888888")">mdi-chart-timeline-variant</MIcon>
                            <MLabel>距离测量</MLabel>
                        </MListItemTitle>
                    </MListItemContent>
                </MListItem>
                <MDivider />
                <MListItem OnClick="StartAreaMeasure">
                    <MListItemContent>
                        <MListItemTitle>
                            <MIcon Size="16" Color="@(IsUsingAreaTool?"#0088E3":"#888888")">mdi-shape-polygon-plus</MIcon>
                            <MLabel>面积测量</MLabel>
                        </MListItemTitle>
                    </MListItemContent>
                </MListItem>
                <MDivider />
                <MListItem OnClick="ClearLayer">
                    <MListItemContent>
                        <MListItemTitle>
                            <MIcon Size="16">mdi-broom</MIcon>
                            <MLabel>清空标记</MLabel>
                        </MListItemTitle>
                    </MListItemContent>
                </MListItem>
                <MDivider />
            </MList>
        </ChildContent>
    </MMenu>
    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="@(()=>IsSaveDraftShow = true)" Color="#888888" @attributes="@context.Attrs">
                <MIcon>mdi-earth-plus</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>保存标绘</span>
        </ChildContent>
    </MTooltip>
    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="SosInfoSearch" Color="@(IsSearchSosInfo?"#C7002D":"#888888")" @attributes="@context.Attrs"> 
                <MIcon>mdi-hospital-box</MIcon>
            </MButton>
        </ActivatorContent>
         <ChildContent>
            <span>救援信息</span>
        </ChildContent>
    </MTooltip>
    <MTooltip Bottom>
        <ActivatorContent>
            <MButton Icon OnClick="TrafficLayer" Color="@(IsTrafficLayerOn?"#4DB6AC":"#888888")" @attributes="@context.Attrs">
                <MIcon>mdi-road-variant</MIcon>
            </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>路况信息</span>
        </ChildContent>
    </MTooltip>
    <MDivider Vertical Inset />
    <MLabel Style="color:white">1</MLabel>
    <MIcon>mdi-account-circle</MIcon>
    <MLabel Style="color:white">1</MLabel>
    <MLabel>@(CurrentUser.Username)</MLabel>
    <MTooltip Bottom>
        <ActivatorContent>
        <MButton Icon OnClick="OpenUserSettinggs" @attributes="@context.Attrs">
            <MIcon>mdi-dots-vertical</MIcon>
        </MButton>
        </ActivatorContent>
        <ChildContent>
            <span>用户信息</span>
        </ChildContent>
    </MTooltip>
</MToolbar>

@*保存标绘窗口*@
<MDialog @bind-Value="IsSaveDraftShow" Width="480" Style="height:200px">
    <MCard Height="200">
        <MFooter Color="#4DB6AC" Style="height:42px;" Padless>
            <MCol Class="text-center" Cols="12">
                <p style="color:white">保存地图标绘</p>
            </MCol>
        </MFooter>
        <MDivider />
        <MContainer>
            <MContainer>
                <MTextField 
                        TValue="string" 
                        Style="width:80%;position:absolute;left:0;right:0;margin:auto;" 
                        Solo Label="输入标绘名称"
                        Hint="请使用中文，英文，数字或下划线" 
                        PrependInnerIcon="mdi-form-textbox"
                        Color="#4DB6AC" @bind-Value="NewDraftName"/>
            </MContainer>
            <MCardActions>
                <MButton Text Color="#4DB6AC"
                         Style="right:20px;position:absolute;bottom:20px"
                         OnClick="SaveDraft">确定</MButton>
                <MButton Text Color="#4DB6AC"
                         Style="right:90px;position:absolute;bottom:20px"
                         OnClick="CancelSaveDraft">取消</MButton>
            </MCardActions>
        </MContainer>
    </MCard>
</MDialog>

    @code {

    /**添加地图，获取用户信息*/
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            await JsRuntime.InvokeVoidAsync("addmap");

            ObjRef = DotNetObjectReference.Create(this);
            await JsRuntime.InvokeVoidAsync("setDotNetHelper", ObjRef);

            CurrentUser = await LocalStorage.GetItemAsync<User>("user");

            var weatherResult = await AuxiliaryFunction.WeatherForecastAsync(new Point(125.332528, 43.838772));
            if (weatherResult.Succeed && weatherResult.Weather is not null)
                CurrentWeather = weatherResult.Weather;

            StateHasChanged();
        }
    }

    #region 基础地图操作

    private async Task ToMapCenter() => await JsRuntime.InvokeVoidAsync("gotomapcenter");

    private async Task ClearLayer() => await JsRuntime.InvokeVoidAsync("clearlayers");

    private async Task StartAddMarker()
    {
        IsUsingDistanceTool = false;
        IsUsingAreaTool = false;
        await JsRuntime.InvokeVoidAsync("startaddMarker");
        IsUsingMarkerTool = true;
        StateHasChanged();
    }

    private async Task StopAddMarker()
    {
        await JsRuntime.InvokeVoidAsync("stopaddMarker");
        IsUsingMarkerTool = false;
        StateHasChanged();
    }

    private async Task StartDistanceMeasure()
    {
        IsUsingMarkerTool = false;
        IsUsingAreaTool = false;
        await JsRuntime.InvokeVoidAsync("DistanceMeasure");
        IsUsingDistanceTool = true;
        StateHasChanged();
    }

    private async Task StopDistanceMeasure()
    {
        await JsRuntime.InvokeVoidAsync("closeDistanceMeasure");
        IsUsingDistanceTool = false;
        StateHasChanged();
    }

    private async Task StartAreaMeasure()
    {
        IsUsingDistanceTool = false;
        IsUsingMarkerTool = false;
        await JsRuntime.InvokeVoidAsync("activedrawingmanager");
        IsUsingAreaTool = true;
        StateHasChanged();
    }

    private async Task StopAreaMeasure()
    {
        await JsRuntime.InvokeVoidAsync("closemeasurearea");
        IsUsingAreaTool = false;
        StateHasChanged();
    }

    private async Task DrawShape(string shape) => await JsRuntime.InvokeVoidAsync("draw", shape);

    #endregion

    private bool DotColorFlag = false;

    private string DotColor
    {
        get
        {
            DotColorFlag = !DotColorFlag;
            if(DotColorFlag)
                return "#E91E63";
            return "#80CBC4";
        }
    }

    private bool AlertColorFlag { get; set; } = false;

    private string AlertColor 
    { 
        get
        {
            AlertColorFlag = !AlertColorFlag;
            if(AlertColorFlag)
                return "#E91E6333";
            return "#80CBC433";
        }
    }

    private int CurrentPage { get; set; } = 0;

    private ResultPageHelper? CurrentPageHelper { get; set; }

    private User CurrentUser { get; set; } = new User();

    private string LoginTime { get; set; } = DateTime.Now.ToString();

    public Weather CurrentWeather { get; set; } = new Weather();

    /**Poi搜索关键字*/
    private string PoiKeyword { get; set; } = string.Empty;

    /**Poi搜索结果*/
    private List<PoiResult> PoiResults { get; set; } = new();

    private List<Draft> DraftsList { get; set; } = new();

    /**是否显示搜索结果*/
    private bool IsSearchResultHidden { get; set; } = true;

    /**是否显示搜索结果*/
    private bool IsRoutePlanningHidden { get; set; } = true;

    /**是否显示搜索设置窗口*/
    private bool IsSearchSettingsShow { get; set; } = false;

    /**是否显示用户设置窗口*/
    private bool IsUserSettingsShow { get; set; } = false;

    /**地点搜索的查询方式*/
    private SearchMode SearchMode { get; set; } = SearchMode.WholeCity;

    /**范围搜索的范围大小*/
    private int Scope { get; set; } = 2000;

    /**是否开启了路况图层*/
    private bool IsTrafficLayerOn { get; set; } = false;

    /**是否正在搜索救援信息*/
    private bool IsSearchSosInfo { get; set; } = false;

    private bool IsUsingTool { get => IsUsingMarkerTool || IsUsingDistanceTool || IsUsingAreaTool; }

    private bool IsUsingMarkerTool { get; set; } = false;

    private bool IsUsingDistanceTool { get; set; } = false;

    private bool IsUsingAreaTool { get; set; } = false;

    private bool IsNoQueryResult { get; set; } = true;

    private bool IsNextPageEnable { get; set; } = true;

    private bool IsPreviousPageEnable { get; set; } = true;

    private bool IsTurningPage { get; set; } = false;

    private bool IsSaveDraftShow { get; set; } = false;

    private bool IsSavingDraft { get; set; } = false;

    private string NewDraftName { get; set; } = string.Empty;

    private List<TravelPoint> TravelPoints { get; set; } = new(8);

    private StringNumber Tactics { get; set; } = 0;

    private StringNumber TravelMode { get; set; } = 2;

    private TravelPoint StartPoint { get; set; } = TravelPoint.DefaultInstance;

    private TravelPoint EndPoint { get; set; } = TravelPoint.DefaultInstance;

    private List<Step>? RouteSteps { get; set; } = null;

    /**用于JS调用Blazor方法*/
    private DotNetObjectReference<Index>? ObjRef { get; set; }

    [JSInvokable]
    public async Task QueryWeather(string locationJson)
    {
        var locaiton = locationJson.ToObject<Location>();
        var weatherResult = await AuxiliaryFunction.WeatherForecastAsync(locaiton.ToPoint());
        var w = weatherResult.Weather;
        if (!weatherResult.Succeed || w is null)
        {
            await PopupService.AlertAsync($"查询天气失败：{weatherResult.Message}，错误码：{weatherResult.StatusCode}", AlertTypes.Error);
            return;
        }

        CurrentWeather = w;
        await PopupService.AlertAsync("查询天气成功，请点击天气栏查看详情", AlertTypes.Success);
        StateHasChanged();
    }

    #region Poi搜索

    /**Poi搜索*/
    private async Task PoiSearch()
    {
        CurrentPageHelper = null;
        CurrentPage = 0;
        if (PoiKeyword is null || PoiKeyword.Trim() == string.Empty)
        {
            await PopupService.AlertAsync("请输入有效的关键字", AlertTypes.Warning);
            return;
        }

        var pageHelper = new ResultPageHelper(PoiKeyword, (TravelMode)TravelMode.AsT1, SearchMode, PoiQuery, TravelSubject, (await JsRuntime.InvokeAsync<string>("getmapcenter")).ToObject<Location>().ToPoint(), Scope);
        var poiResult = await pageHelper.NextPage();

        if (poiResult.StatusCode is Code.NoQueryResult)
        {
            IsNoQueryResult = true;
            IsSearchResultHidden = false;
            StateHasChanged();
            return;
        }

        if (!poiResult.Succeed)
        {
            await PopupService.AlertAsync($"查询出现错误：{poiResult.Message}，错误码：{poiResult.StatusCode}", AlertTypes.Error);
            return;
        }

        var pois = poiResult.Pois;
        if (pois is null || pois.results is null)
        {
            await PopupService.AlertAsync("查询成功，但解析结果出错", AlertTypes.Error);
            return;
        }

        PoiResults = pois.results;
        IsNoQueryResult = false;
        IsSearchResultHidden = false;
        CurrentPageHelper = pageHelper;
        StateHasChanged();
    }

    [JSInvokable]
    public async Task<string?> PointDecode(string pointJson)
    {
        var location = pointJson.ToObject<Location>();
        var result = await PoiQuery.LocationDecodeQueryAsync(location);

        if (!result.Succeed)
        {
            await PopupService.AlertAsync($"地址解码错误：{result.Message}，错误码{result.StatusCode}");
            return null;
        }

        return result.Address;
    }

    private async Task NextPage()
    {
        if (CurrentPageHelper is null)
            return;

        if (IsTurningPage)
            return;

        IsTurningPage = true;
        var result = await CurrentPageHelper.NextPage();

        if (result.StatusCode is Code.NoQueryResult)
        {
            await PopupService.AlertAsync("已经是最后一页了！", AlertTypes.Warning);
            IsTurningPage = false;
            return;
        }

        if (!result.Succeed)
        {
            await PopupService.AlertAsync($"查询出现错误：{result.Message}，错误码：{result.StatusCode}", AlertTypes.Error);
            IsTurningPage = false;
            return;
        }

        var pois = result.Pois;
        if (pois is null || pois.results is null)
        {
            await PopupService.AlertAsync("查询成功，但解析结果出错", AlertTypes.Error);
            IsTurningPage = false;
            return;
        }

        CurrentPage += 1;
        IsTurningPage = false;
        PoiResults = pois.results;
        StateHasChanged();
    }

    private async Task PreviousPage()
    {
        if (CurrentPageHelper is null)
            return;

        if (IsTurningPage)
            return;

        if (CurrentPage is 0)
        {
            await PopupService.AlertAsync("已经是第一页了！", AlertTypes.Warning);
            return;
        }

        IsTurningPage = true;
        var result = await CurrentPageHelper.PreviousPage();

        if (!result.Succeed)
        {
            await PopupService.AlertAsync($"查询出现错误：{result.Message}，错误码：{result.StatusCode}", AlertTypes.Error);
            IsTurningPage = false;
            return;
        }

        var pois = result.Pois;
        if (pois is null || pois.results is null)
        {
            await PopupService.AlertAsync("查询成功，但解析结果出错", AlertTypes.Error);
            IsTurningPage = false;
            return;
        }

        CurrentPage -= 1;
        IsTurningPage = false;
        PoiResults = pois.results;
        StateHasChanged();
    }

    /**跳转到Poi*/
    private async Task GoToPoi(MouseEventArgs args, PoiResult? poiResult)
    {
        if (poiResult is null)
        {
            await PopupService.AlertAsync("地点解析出错", AlertTypes.Error);
            return;
        }

        await JsRuntime.InvokeVoidAsync("addSingleMarker", poiResult.ToJson());
    }

    #endregion

    #region 路径规划

    private async Task SelectStartPoint()
    {
        await PopupService.AlertAsync("请在地图上单击选择出发地", AlertTypes.None);
        await JsRuntime.InvokeVoidAsync("selectTravelPoint", 0);
    }

    private async Task SelectEndPoint()
    {
        await PopupService.AlertAsync("请在地图上单击选择目的地", AlertTypes.None);
        await JsRuntime.InvokeVoidAsync("selectTravelPoint", 1);
    }

    private async Task SelectTravelPoint()
    {
        if (TravelPoints.Count is 8)
        {
            await PopupService.AlertAsync("经过点数量已到达最大值", AlertTypes.Warning);
            return;
        }

        await PopupService.AlertAsync("请在地图上单击选择经过地", AlertTypes.None);
        await JsRuntime.InvokeVoidAsync("selectTravelPoint", 2);
    }

    private async Task RemoveTravelPoint(TravelPoint travelPoint)
    {
        if (TravelPoints.Remove(travelPoint))
        {
            await PopupService.AlertAsync("成功删除经过点", AlertTypes.Success);
            return;
        }
        await PopupService.AlertAsync("删除经过点失败", AlertTypes.Success);
    }

    [JSInvokable]
    public async Task SetStartPoint(string infoJson)
    {
        StartPoint = infoJson.ToObject<TravelPoint>();
        await PopupService.AlertAsync("成功选择出发地", AlertTypes.Success);
        StateHasChanged();
    }

    [JSInvokable]
    public async Task SetEndPoint(string infoJson)
    {
        EndPoint = infoJson.ToObject<TravelPoint>();
        await PopupService.AlertAsync("成功选择目的地", AlertTypes.Success);
        StateHasChanged();
    }

    [JSInvokable]
    public async Task AddTravelPoint(string infoJson)
    {
        TravelPoints.Add(infoJson.ToObject<TravelPoint>());
        await PopupService.AlertAsync("成功选择经过地", AlertTypes.Success);
        StateHasChanged();
    }

    private async Task SearchRoute()
    {
        if(StartPoint == TravelPoint.DefaultInstance)
        {
            await PopupService.AlertAsync("请选择出发地", AlertTypes.Warning);
            return;
        }

        if(EndPoint == TravelPoint.DefaultInstance)
        {
            await PopupService.AlertAsync("请选择目的地", AlertTypes.Warning);
            return;
        }

        var travelPoints = new List<TravelPoint>(10);
        travelPoints.Add(StartPoint);
        travelPoints.AddRange(TravelPoints);
        travelPoints.Add(EndPoint);

        var points=new List<Point>(10);
        travelPoints.ForEach(async (item) => 
        {
            if(item is null)
            {
                await PopupService.AlertAsync("解析地点位置时出现空引用", AlertTypes.Error);
                return;
            }

            var pos=item.Position;
            if(pos is null)
            {
                await PopupService.AlertAsync("解析地点位置时出现空引用", AlertTypes.Error);
                return;
            }

            points.Add(pos.ToPoint());
        });

        var planningResult = await TravelSubject.TravelRoutePlanningAsync((TravelMode)TravelMode.AsT1, points.ToArray());

        if(!planningResult.Succeed)
        {
            await PopupService.AlertAsync($"路线规划出错：{planningResult.Message}，错误码：{planningResult.StatusCode}", AlertTypes.Error);
            return;
        }

        RouteSteps = planningResult.Steps;
        await JsRuntime.InvokeVoidAsync("addPath", RouteSteps);
    }

    #endregion

    /**路况图层*/
    private async Task TrafficLayer()
    {
        IsTrafficLayerOn = !IsTrafficLayerOn;
        await JsRuntime.InvokeVoidAsync("trafficlayer");
    }

    #region 救援信息查询

    /**救援信息查询*/
    private async Task SosInfoSearch()
    {
        if (IsSearchSosInfo)
        {
            await JsRuntime.InvokeVoidAsync("cancelselectsospoint");
            IsSearchSosInfo = false;
            StateHasChanged();
            return;
        }

        try
        {
            IsSearchSosInfo = true;
            await PopupService.AlertAsync("请选择事故点");
            await JsRuntime.InvokeVoidAsync("selectsospoint", ObjRef);
        }
        catch
        {
            IsSearchSosInfo = false;
            throw;
        }
    }

    [JSInvokable]
    public async Task SearchSosInfo(string pointJson)
    {
        var sosPoint = pointJson.ToObject<Location>().ToPoint();
        if (sosPoint is null)
        {
            await PopupService.AlertAsync("解析救援点出错", AlertTypes.Error);
            return;
        }

        var queryReult = await TravelSubject.RescueInfoQueryAsync(sosPoint);
        var route = queryReult.RecommendedRoute;

        if (!queryReult.Succeed)
        {
            await PopupService.AlertAsync($"查询出现错误：{queryReult.Message}，错误码：{queryReult.StatusCode}", AlertTypes.Error);
            return;
        }

        if (route is null)
        {
            await PopupService.AlertAsync($"路线解析为空：{queryReult.Message}，错误码：{queryReult.StatusCode}", AlertTypes.Error);
            return;
        }

        await JsRuntime.InvokeVoidAsync("addSosFeature",
        new
        {
            Route = route,
            Distance = queryReult.Distance,
            Duration = queryReult.Duration,
            Address = queryReult.RecommendedHospital?.address,
            Name = queryReult.RecommendedHospital?.name,
            Tel = queryReult.RecommendedHospital?.telephone
        }.ToJson());
        RouteSteps = route;
        IsRoutePlanningHidden = false;
        StateHasChanged();
    }

    #endregion

    private async Task OpenUserSettinggs()
    {
        IsUserSettingsShow = true;
        var queryRsult = await AuxiliaryFunction.QueryUserDraftListAsync(CurrentUser);
        var list = queryRsult.DraftList;
        if (!queryRsult.Succeed)
        {
            await PopupService.AlertAsync($"获取用户标绘列表失败：{queryRsult.Message}，错误码：{queryRsult.StatusCode}");
            return;
        }
        if (list is null)
        {
            await PopupService.AlertAsync($"获取用户标绘列表成功，但解析为空");
            return;
        }
        DraftsList = list;
    }

    #region 地图标绘操作

    private async Task LoadDraft(Draft draft)
    {
        var result = await AuxiliaryFunction.QueryDeepCopyOf(draft.ID, CurrentUser);

        if(!result.Succeed)
        {
            await PopupService.AlertAsync($"获取标绘失败：{result.Message}，错误码：{result.StatusCode}", AlertTypes.Error);
            return;
        }

        var draft1 = result.UserDraft;
        if(draft1 is null)
        {
            await PopupService.AlertAsync($"解析标绘出错", AlertTypes.Error);
            return;
        }

        var points = draft1.Points;
        var polylines = draft1.LineStrings;
        var polygons = draft1.Polygons;

        var ptInfo = new List<Location>(points.Count);
        var plInfo = new List<IEnumerable<Location>>(polylines.Count);
        var pgInfo = new List<IEnumerable<Location>>(polygons.Count);

        points.ForEach((item) => 
        {
            ptInfo.Add(new Location(item));
        });
        polylines.ForEach((item) => 
        {
            var cos = item.Coordinates;
            var pts = new List<Location>(cos.Count);
            cos.ForEach((item1) => pts.Add(new Location() { lng = item1.X, lat = item1.Y }));
            plInfo.Add(pts);
        });
        polygons.ForEach((item) => 
        {
            var cos = item.ExteriorRing;
            var pts = new List<Location>(cos.Count);
            cos.ForEach((item1) => pts.Add(new Location() { lng = item1.X, lat = item1.Y }));
            pts.RemoveAt(pts.Count - 1);
            pgInfo.Add(pts);
        });

        string info = (new
        {
            Points = ptInfo,
            Polylines = plInfo,
            Polygons = pgInfo,
            Zoom = Convert.ToInt32(draft.Zoom),
            Lng = draft.Lng,
            Lat = draft.Lat,
        }).ToJson();
        await ClearLayer();
        await JsRuntime.InvokeVoidAsync("addAnnotations", info);
        await PopupService.AlertAsync("标绘加载完成", AlertTypes.Success);
        IsUserSettingsShow = false;
    }

    private async Task DeleteDraft(int draftID)
    {
        var delResult = await AuxiliaryFunction.DeleteUserDraftAsync(CurrentUser, draftID);
        if(!delResult.Succeed)
        {
            await PopupService.AlertAsync($"删除标绘失败:{delResult.Message}，错误码：{delResult.StatusCode}", AlertTypes.Error);
            return;
        }
        await OpenUserSettinggs();
        StateHasChanged();
        await PopupService.AlertAsync("删除标绘成功", AlertTypes.Success);
    }

    private async Task SaveDraft()
    {
        if (IsSavingDraft)
            return;
        IsSavingDraft = true;

        if(string.IsNullOrEmpty(NewDraftName) || string.IsNullOrWhiteSpace(NewDraftName))
        {
            await PopupService.AlertAsync("标绘名称格式不符合要求", AlertTypes.Error);
            return;
        }

        var draft = (await JsRuntime.InvokeAsync<string>("getDraftBasicInfo")).ToObject<Draft>();
        draft.Name = NewDraftName;
        draft.CreateTime = DateTime.Now;
        draft.OwnerID = CurrentUser.Account;

        var info = (await JsRuntime.InvokeAsync<string>("collectAnnotations")).ToObject<AnnotationReceiver>();
        draft.AddAnnotations(info.GetGeometries());

        var result = await AuxiliaryFunction.CreateUserDraftAsync(CurrentUser, draft);
        if (!result.Succeed)
        {
            await PopupService.AlertAsync($"创建标绘失败：{result.Message}，错误码：{result.StatusCode}", AlertTypes.Error);
            return;
        }

        await PopupService.AlertAsync($"创建标绘：{draft.Name}成功", AlertTypes.Success);

        IsSavingDraft = false;
        IsSaveDraftShow = false;
    }

    private void CancelSaveDraft()
    {
        IsSaveDraftShow = false;
        NewDraftName = string.Empty;
    }

    #endregion

    public void Dispose() => ObjRef?.Dispose();

}